---
title: Environment Variables
description: How to configure environment variables in next-forge.
---

next-forge uses environment variables for configuration. This guide will help you set up the required variables to get started quickly, and optionally configure additional features.

## Quick Start (Minimum Setup)

To get next-forge running locally with basic functionality, you only need to configure these **required** variables:

### 1. Database (Required)

Add to `packages/database/.env`:

```bash
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
```

<Tip>
  For quick local development, we recommend [Neon](https://neon.tech) for a free PostgreSQL database. Sign up, create a project, and copy the connection string.
</Tip>

### 2. Authentication (Required)

Add to `apps/app/.env.local` and `apps/web/.env.local`:

```bash
# Server
CLERK_SECRET_KEY="sk_test_..."

# Client
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_..."
NEXT_PUBLIC_CLERK_SIGN_IN_URL="/sign-in"
NEXT_PUBLIC_CLERK_SIGN_UP_URL="/sign-up"
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL="/"
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL="/"
```

<Steps>

<Step>
  Sign up at [Clerk](https://clerk.com) and create an application
</Step>

<Step>
  Go to **API Keys** in your Clerk dashboard
</Step>

<Step>
  Copy the **Publishable key** (starts with `pk_`) and **Secret key** (starts with `sk_`)
</Step>

</Steps>

### 3. Local URLs (Pre-configured)

These are already set to sensible defaults for local development:

```bash
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NEXT_PUBLIC_WEB_URL="http://localhost:3001"
NEXT_PUBLIC_API_URL="http://localhost:3002"
NEXT_PUBLIC_DOCS_URL="http://localhost:3004"
VERCEL_PROJECT_PRODUCTION_URL="http://localhost:3000"
```

**That's it!** You can now run `npm run dev` and the app will work with basic authentication and database functionality.

## Optional Features

The following environment variables enable additional features. You can add them as needed:

### Content Management (BaseHub)

Required for the CMS functionality in `packages/cms`.

```bash
BASEHUB_TOKEN="bshb_..."
```

<Steps>

<Step>
  Fork the [next-forge template](https://basehub.com/basehub/next-forge?fork=1) on BaseHub
</Step>

<Step>
  Navigate to **Settings → API Tokens**
</Step>

<Step>
  Copy your **Read Token** (starts with `bshb_`)
</Step>

</Steps>

### Email (Resend)

Required for sending transactional emails.

```bash
RESEND_TOKEN="re_..."
RESEND_FROM="noreply@yourdomain.com"
```

[Get your API key from Resend](https://resend.com/api-keys)

### Payments (Stripe)

Required for subscription and payment functionality.

```bash
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
```

<Steps>

<Step>
  Get your keys from [Stripe Dashboard](https://dashboard.stripe.com/apikeys)
</Step>

<Step>
  For webhooks, install the [Stripe CLI](https://stripe.com/docs/stripe-cli) and run:
  ```bash
  stripe listen --forward-to localhost:3000/api/webhooks/stripe
  ```
</Step>

</Steps>

### Analytics

#### Google Analytics

```bash
NEXT_PUBLIC_GA_MEASUREMENT_ID="G-..."
```

[Create a GA4 property](https://analytics.google.com/)

#### PostHog

```bash
NEXT_PUBLIC_POSTHOG_KEY="phc_..."
NEXT_PUBLIC_POSTHOG_HOST="https://app.posthog.com"
```

[Get your keys from PostHog](https://app.posthog.com/project/settings)

### Observability

#### Better Stack (Uptime monitoring)

```bash
BETTERSTACK_API_KEY="..."
BETTERSTACK_URL="..."
```

[Get your API key from Better Stack](https://betterstack.com/logs)

### Security

#### Arcjet (Rate limiting & security)

```bash
ARCJET_KEY="ajkey_..."
```

[Get your key from Arcjet](https://app.arcjet.com/)

### Real-time Features

#### Liveblocks (Collaboration)

```bash
LIVEBLOCKS_SECRET="sk_..."
```

[Get your secret from Liveblocks](https://liveblocks.io/dashboard)

### Notifications (Knock)

```bash
KNOCK_API_KEY="..."
KNOCK_SECRET_API_KEY="..."
KNOCK_FEED_CHANNEL_ID="..."
NEXT_PUBLIC_KNOCK_API_KEY="..."
NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID="..."
```

[Get your keys from Knock](https://dashboard.knock.app/)

### Feature Flags

```bash
FLAGS_SECRET="..."
```

Generate a random secret string for encrypting feature flag data.

### Webhooks (Svix)

```bash
SVIX_TOKEN="..."
```

[Get your token from Svix](https://dashboard.svix.com/)

### Clerk Webhooks

```bash
CLERK_WEBHOOK_SECRET="whsec_..."
```

<Steps>

<Step>
  In your Clerk dashboard, go to **Webhooks**
</Step>

<Step>
  Add a new endpoint pointing to `https://your-domain.com/api/webhooks/clerk`
</Step>

<Step>
  Subscribe to the events you need (typically `user.created`, `user.updated`, etc.)
</Step>

<Step>
  Copy the **Signing Secret**
</Step>

</Steps>

## Environment Variable Files

next-forge uses environment variables across multiple locations:

| File | Purpose |
|------|---------|
| `apps/app/.env.local` | Main application variables |
| `apps/web/.env.local` | Marketing website variables |
| `apps/api/.env.local` | API server variables |
| `packages/database/.env` | Database connection string |
| `packages/cms/.env.local` | CMS configuration |
| `packages/internationalization/.env.local` | i18n configuration |

<Info>
  The setup script automatically creates these files from `.env.example` templates. You only need to fill in the values.
</Info>

## Type Safety

Type safety is provided by [@t3-oss/env-nextjs](https://env.t3.gg/), which provides runtime validation and autocompletion for all environment variables. Each package defines its own environment variables in a `keys.ts` file with Zod validation schemas.

### Validation Rules

<Tip>
  Be as specific as possible with validation. For example, if a vendor secret starts with `sec_`, validate it as `z.string().min(1).startsWith('sec_')`. This makes your intent clearer and helps prevent errors at runtime.
</Tip>

## Adding a New Environment Variable

To add a new environment variable:

1. Add the variable to the relevant `.env.local` files
2. Add validation to the `server` or `client` object in the package's `keys.ts` file

Example in `packages/my-package/keys.ts`:

```ts
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const keys = createEnv({
  server: {
    MY_NEW_SECRET: z.string().min(1),
  },
  client: {
    NEXT_PUBLIC_MY_VALUE: z.string().optional(),
  },
  runtimeEnv: {
    MY_NEW_SECRET: process.env.MY_NEW_SECRET,
    NEXT_PUBLIC_MY_VALUE: process.env.NEXT_PUBLIC_MY_VALUE,
  },
});
```

## Deployment

When deploying to Vercel or other platforms:

1. Add all required environment variables to your deployment platform
2. Update URL variables (`NEXT_PUBLIC_APP_URL`, etc.) to production values
3. Some integrations (like Sentry) automatically inject their variables via marketplace integrations

<Info>
  Variables prefixed with `VERCEL_` are automatically available in Vercel deployments, such as `VERCEL_PROJECT_PRODUCTION_URL`.
</Info>
